home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / include / sys / scsi.h < prev    next >
C/C++ Source or Header  |  1992-03-06  |  35KB  |  928 lines

  1. /*
  2.  * scsi.h --
  3.  *
  4.  *    Common declarations for SCSI command formaters. This file only covers
  5.  *    definitions pertaining to the SCSI common command set that are
  6.  *    common to all SCSI device types (ie disk, tapes, WORM, printers, etc).
  7.  *    Device sepecific command format can be found in scsi{Disk,Tape,WORM}.h
  8.  *    SCSI protocol releated declarations can be found in scsiHBA.h.
  9.  *    Definitions for the SCSI device sub-system. Some of the following
  10.  *      references from the proceedings of the 1984 Mini/Micro Northeast
  11.  *    Conference might be useful in understanding SCSI. 
  12.  *
  13.  *
  14.  * Copyright 1988 Regents of the University of California
  15.  * Permission to use, copy, modify, and distribute this
  16.  * software and its documentation for any purpose and without
  17.  * fee is hereby granted, provided that the above copyright
  18.  * notice appear in all copies.  The University of California
  19.  * makes no representations about the suitability of this
  20.  * software for any purpose.  It is provided "as is" without
  21.  * express or implied warranty.
  22.  *
  23.  * $Header: /sprite/src/lib/include/sys/RCS/scsi.h,v 1.4 92/03/06 12:16:38 mani Exp Locker: mani $ SPRITE (Berkeley)
  24.  */
  25.  
  26. #ifndef _SCSI_H
  27. #define _SCSI_H
  28.  
  29. #include <machparam.h>
  30.  
  31. #ifndef BYTE_ORDER
  32. BYTE_ORDER is not defined
  33. #endif
  34. /*
  35.  * "Standard" SCSI Commands. SCSI command are divided into 8 group as
  36.  * follows:
  37.  *    Group0    (0x00 - 0x1f).  Basic commands. 6 bytes long
  38.  *    Group1    (0x20 - 0x3f).  Extended command. 10 bytes.
  39.  *    Group2    (0x40 - 0x5f).    Reserved.
  40.  *    Group2    (0x60 - 0x7f).    Reserved.
  41.  *    Group2    (0x80 - 0x9f).    Reserved.
  42.  *    Group2    (0xa0 - 0xbf).    Reserved.
  43.  *    Group6    (0xc0 - 0xdf).    Vendor Unique
  44.  *    Group7    (0xe0 - 0xff).  Vendor Unique
  45.  *    
  46.  *
  47.  */
  48.  
  49. /*
  50.  * Scsi Group0 commands all are 6 bytes and have a format according to 
  51.  * struct ScsiGroup0Cmd.
  52.  */
  53.  
  54. #define SCSI_TEST_UNIT_READY    0x00
  55. #define SCSI_REZERO_UNIT    0x01
  56. #define SCSI_REQUEST_SENSE    0x03
  57. #define    SCSI_FORMAT_UNIT    0x04
  58. #define SCSI_REASSIGN_BLOCKS    0x07
  59. #define SCSI_READ        0x08
  60. #define SCSI_WRITE        0x0a
  61. #define SCSI_SEEK        0x0b
  62. #define SCSI_INQUIRY        0x12
  63. #define SCSI_MODE_SELECT    0x15
  64. #define    SCSI_RESERVE_UNIT    0x16
  65. #define    SCSI_RELEASE_UNIT    0x17
  66. #define SCSI_COPY        0x18
  67. #define SCSI_MODE_SENSE        0x1A
  68. #define SCSI_START_STOP        0x1b
  69. #define    SCSI_RECV_DIAG_RESULTS    0x1c
  70. #define SCSI_SEND_DIAGNOSTIC    0x1d
  71. #define SCSI_PREVENT_ALLOW     0x1e
  72. /*
  73.  * Group1 commands are all 10 bytes and have a format according to
  74.  * struct ScsiGroup1Cmd.
  75.  */
  76. #define SCSI_READ_CAPACITY     0x25    
  77. #define    SCSI_READ_EXT        0x28
  78. #define    SCSI_WRITE_EXT        0x2a
  79. #define    SCSI_SEEK_EXT        0x2b
  80. #define    SCSI_WRITE_VERIFY    0x2e
  81. #define    SCSI_VERIFY_EXT        0x2f
  82. #define    SCSI_SEARCH_HIGH    0x30
  83. #define SCSI_SEARCH_EQUAL    0x31
  84. #define    SCSI_SEARCH_LOW        0x32
  85. #define    SCSI_SET_LIMITS        0x33
  86. #define    SCSI_COMPARE        0x39
  87. #define    SCSI_COPY_VERIFY    0x3a
  88.  
  89.  
  90. /*
  91.  * Group-0 commands for sequential access devices.
  92.  */
  93.  
  94. #define SCSI_REWIND        0x01
  95. #define SCSI_READ_BLOCK_LIMITS    0x05
  96. #define    SCSI_TRACK_SELECT    0x0b
  97. #define    SCSI_READ_REVERSE    0x0f
  98. #define SCSI_WRITE_EOF        0x10
  99. #define SCSI_SPACE        0x11
  100. #define    SCSI_VERIFY        0x13
  101. #define    SCSI_READ_BUFFER    0x14
  102. #define SCSI_ERASE_TAPE        0x19
  103. #define    SCSI_LOAD_UNLOAD    0x1b
  104.  
  105. /*
  106.  * Group-1 commands for sequential access devices.
  107.  */
  108. #define SCSI_LOCATE        0x2b
  109. #define SCSI_READ_POSITION    0x34
  110.  
  111. /*
  112.  * Commands for a medium-changer (jukebox) device.
  113.  */
  114. #define SCSI_MOVE_MEDIUM    0xa5
  115. #define SCSI_POSITION_ELEMENT    0x2b
  116. #define SCSI_INIT_ELEM_STATUS    0xe7
  117. #define SCSI_READ_ELEM_STATUS    0xb8
  118.  
  119.  
  120. /*
  121.  * The standard group-0 6-byte SCSI control block.  Note that the 
  122.  * fields between highAddr and blockCount inclusive are command dependent.
  123.  * The definitions Addr and BlockCount cover most of the commands we will
  124.  * use.
  125.  */
  126.  
  127. typedef struct ScsiGroup0Cmd {
  128. #if BYTE_ORDER == BIG_ENDIAN
  129.     unsigned char command;        /* command code, defined below.  The
  130.                      * upper three bits of this are zero
  131.                      * to indicate the control block is
  132.                      * only 6 bytes long */
  133.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  134.                      * pass the command.  The device
  135.                      * has already been selected using
  136.                      * the "targetID" bit. */
  137.     unsigned char highAddr    :5;    /* High bits of address */
  138.     unsigned char midAddr;        /* Middle bits of address */
  139.     unsigned char lowAddr;        /* Low bits of address */
  140.     unsigned char blockCount;        /* Blocks to transfer */
  141.     unsigned char vendor57    :1;    /* Vendor unique bit */
  142.     unsigned char vendor56    :1;    /* Vendor unique bit */
  143.     unsigned char pad1        :4;    /* Reserved */
  144.     unsigned char linkIntr    :1;    /* Interrupt after linked command */
  145.     unsigned char link        :1;    /* Another command follows */
  146. #else
  147.     unsigned char command;        /* command code, defined below.  The
  148.                      * upper three bits of this are zero
  149.                      * to indicate the control block is
  150.                      * only 6 bytes long */
  151.     unsigned char highAddr    :5;    /* High bits of address */
  152.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  153.                      * pass the command.  The device
  154.                      * has already been selected using
  155.                      * the "targetID" bit. */
  156.     unsigned char midAddr;        /* Middle bits of address */
  157.     unsigned char lowAddr;        /* Low bits of address */
  158.     unsigned char blockCount;        /* Blocks to transfer */
  159.     unsigned char link        :1;        /* Another command follows */
  160.     unsigned char linkIntr    :1;    /* Interrupt after linked command */
  161.     unsigned char pad1        :4;    /* Reserved */
  162.     unsigned char vendor56    :1;    /* Vendor unique bit */
  163.     unsigned char vendor57    :1;    /* Vendor unique bit */
  164. #endif
  165. } ScsiGroup0Cmd;
  166.  
  167. /*
  168.  * SCSI status completion information.  This is returned by the device
  169.  * when a command completes. 
  170.  */
  171.  
  172. typedef struct ScsiStatus {
  173. #if BYTE_ORDER == BIG_ENDIAN
  174.     unsigned char reserved    :1;    /* Reserved. */
  175.     unsigned char vendor06    :1;    /* Vendor unique bit */
  176.     unsigned char vendor05    :1;    /* Vendor unique bit */
  177.     unsigned char intStatus    :1;    /* Intermediate status */
  178.     unsigned char busy        :1;    /* Device busy or reserved */
  179.     unsigned char conditionMet    :1;    /* Condition met */
  180.     unsigned char check        :1;    /* Check the sense data for more info */
  181.     unsigned char vendor00    :1;    /* Vendor unique bit */
  182. #else
  183.     unsigned char vendor00    :1;    /* Vendor unique bit */
  184.     unsigned char check        :1;    /* Check the sense data for more info */
  185.     unsigned char conditionMet    :1;    /* Condition met */
  186.     unsigned char busy        :1;    /* Device busy or reserved */
  187.     unsigned char intStatus    :1;    /* Intermediate status */
  188.     unsigned char vendor05    :1;    /* Vendor unique bit */
  189.     unsigned char vendor06    :1;    /* Vendor unique bit */
  190.     unsigned char reserved    :1;    /* Reserved. */
  191. #endif
  192. } ScsiStatus;
  193.  
  194. /*
  195.  * SCSI_RESERVED_STATUS() - Return TRUE if the status byte has a reserved code.
  196.  */
  197.  
  198. #define    SCSI_RESERVED_STATUS(byte) (byte&0x80)
  199.  
  200.  
  201. /*
  202.  * Sense information provided after some errors.  This is divided into
  203.  * two kinds, classes 0-6, and class 7.  This is 30 bytes big to allow
  204.  * for the drive specific sense bytes that follow the standard 4 byte header.
  205.  *
  206.  * For extended sense, this buffer may be cast into another type.  Also
  207.  * The actual size of the sense data returned is used to detect what
  208.  * kind of tape drive is out there.  Kludgy, but true.
  209.  */
  210. typedef struct ScsiClass0Sense {
  211. #if BYTE_ORDER == BIG_ENDIAN
  212.     unsigned char valid        :1;    /* Sense data is valid */
  213.     unsigned char error        :7;    /* 3 bits class and 4 bits code */
  214.     unsigned char highAddr;        /* High byte of block address */
  215.     unsigned char midAddr;        /* Middle byte of block address */
  216.     unsigned char lowAddr;        /* Low byte of block address */
  217.     unsigned char sense[26];        /* Target specific sense data */
  218. #else
  219.     unsigned char error        :7;    /* 3 bits class and 4 bits code */
  220.     unsigned char valid        :1;    /* Sense data is valid */
  221.     unsigned char highAddr;        /* High byte of block address */
  222.     unsigned char midAddr;        /* Middle byte of block address */
  223.     unsigned char lowAddr;        /* Low byte of block address */
  224.     unsigned char sense[26];        /* Target specific sense data */
  225. #endif
  226. } ScsiClass0Sense;
  227.  
  228. /*
  229.  * Definitions for errors in the sense data.  The error field is specified
  230.  * as a 3 bit class and 4 bit code, but it is easier to treat it as a
  231.  * single 7 bit field.
  232.  */
  233. #define SCSI_NO_SENSE_DATA        0x00
  234. #define SCSI_NOT_READY            0x04
  235. #define SCSI_NOT_LOADED            0x09
  236. #define SCSI_INSUF_CAPACITY        0x0a
  237. #define SCSI_HARD_DATA_ERROR        0x11
  238. #define SCSI_WRITE_PROTECT        0x17
  239. #define SCSI_CORRECTABLE_ERROR        0x18
  240. #define SCSI_FILE_MARK            0x1c
  241. #define SCSI_INVALID_COMMAND        0x20
  242. #define SCSI_UNIT_ATTENTION        0x30
  243. #define SCSI_END_OF_MEDIA        0x34
  244.  
  245. /*
  246.  * The standard "extended" sense data returned by SCSI devices.  This
  247.  * has an error field of 0x70, for a "class 7" error.
  248.  */
  249. typedef struct ScsiClass7Sense {
  250. #if BYTE_ORDER == BIG_ENDIAN
  251.     unsigned char valid        :1;    /* Sense data is valid */
  252.     unsigned char error7    :7;    /* == 0x70 */
  253.     unsigned char pad1;            /* Also "segment number" for copy */
  254.     unsigned char fileMark    :1;    /* File mark on device */
  255.     unsigned char endOfMedia    :1;    /* End of media reached */
  256.     unsigned char badBlockLen    :1;    /* Block length mis-match (Exabyte) */
  257.     unsigned char pad2        :1;
  258.     unsigned char key        :4;    /* Sense keys defined below */
  259.     unsigned char info1;        /* Information byte 1 */
  260.     unsigned char info2;        /* Information byte 2 */
  261.     unsigned char info3;        /* Information byte 3 */
  262.     unsigned char info4;        /* Information byte 4 */
  263.     unsigned char length;        /* Number of additional info bytes */
  264. #else
  265.     unsigned char error7    :7;    /* == 0x70 */
  266.     unsigned char valid        :1;    /* Sense data is valid */
  267.     unsigned char pad1;            /* Also "segment number" for copy */
  268.     unsigned char key        :4;    /* Sense keys defined below */
  269.     unsigned char pad2        :1;
  270.     unsigned char badBlockLen    :1;    /* Block length mis-match (Exabyte) */
  271.     unsigned char endOfMedia    :1;    /* End of media reached */
  272.     unsigned char fileMark    :1;    /* File mark on device */
  273.     unsigned char info1;        /* Information byte 1 */
  274.     unsigned char info2;        /* Information byte 2 */
  275.     unsigned char info3;        /* Information byte 3 */
  276.     unsigned char info4;        /* Information byte 4 */
  277.     unsigned char length;        /* Number of additional info bytes */
  278. #endif
  279. } ScsiClass7Sense;            /* 8 Bytes */
  280.  
  281. /*
  282.  * Key values for standardized sense class 7. 
  283.  */
  284. #define SCSI_CLASS7_NO_SENSE        0
  285. #define SCSI_CLASS7_RECOVERABLE    1
  286. #define SCSI_CLASS7_NOT_READY        2
  287. #define SCSI_CLASS7_MEDIA_ERROR    3
  288. #define SCSI_CLASS7_HARDWARE_ERROR    4
  289. #define SCSI_CLASS7_ILLEGAL_REQUEST    5
  290.  
  291. /*
  292.  * These seem to have different meanings to different vendors....
  293.  */
  294. #define SCSI_CLASS7_MEDIA_CHANGE    6
  295. #define SCSI_CLASS7_UNIT_ATTN        6
  296.  
  297. #define SCSI_CLASS7_WRITE_PROTECT    7
  298. #define SCSI_CLASS7_BLANK_CHECK        8
  299. #define SCSI_CLASS7_VENDOR        9
  300. #define SCSI_CLASS7_POWER_UP_FAILURE    10
  301. #define SCSI_CLASS7_ABORT        11
  302. #define SCSI_CLASS7_EQUAL        12
  303. #define SCSI_CLASS7_OVERFLOW        13
  304. #define SCSI_CLASS7_RESERVED_14        14
  305. #define SCSI_CLASS7_RESERVED_15        15
  306.  
  307. /*
  308.  * Maximum size of sense data that a device can return. 
  309.  */
  310. #define    SCSI_MAX_SENSE_LEN    256
  311.  
  312. /*
  313.  * Data return by the SCSI inquiry command. 
  314.  */
  315.  
  316. typedef struct ScsiInquiryData {
  317. #if BYTE_ORDER == BIG_ENDIAN
  318.     unsigned char     type;        /* Peripheral Device type. See below. */
  319.     unsigned char     rmb:1;        /* Removable Medium bit. */
  320.     unsigned char    qualifier:7;     /* Device type qualifier. */
  321.     unsigned char    version;    /* Version info. */
  322.     unsigned char    reserved:4;    /* reserved. */
  323.     unsigned char    format:4;    /* Response format. */
  324.     unsigned char    length;        /* length of data returned. */
  325. #ifdef notdef
  326.     unsigned char    vendor;        /* Vendor unqiue parameter. */
  327.     unsigned char    reserved2[2];    /* More reserved. */
  328.     char        vendorInfo[8];    /* Vector identification. */
  329.     char        productInfo[8]; /* Product identification. */
  330.     char        firmwareInfo[4]; /* Firmware identification. */
  331. #endif
  332.  
  333.     unsigned char    reserved2[3];    /* Reserved                  */
  334.     unsigned char    vendorID[8];    /* Vendor ID (ASCII)              */
  335.     unsigned char    productID[16];    /* Product ID (ASCII)              */
  336.     unsigned char    revLevel[4];    /* Revision level (ASCII)          */
  337.     unsigned char    revData[8];    /* Revision data (ASCII)          */
  338. #else
  339.     unsigned char     type;        /* Peripheral Device type. See below. */
  340.     unsigned char    qualifier:7;     /* Device type qualifier. */
  341.     unsigned char     rmb:1;        /* Removable Medium bit. */
  342.     unsigned char    version;    /* Version info. */
  343.     unsigned char    format:4;    /* Response format. */
  344.     unsigned char    reserved:4;    /* reserved. */
  345.     unsigned char    length;        /* length of data returned. */
  346.     unsigned char    reserved2[3];    /* Reserved                  */
  347.     unsigned char    vendorID[8];    /* Vendor ID (ASCII)              */
  348.     unsigned char    productID[16];    /* Product ID (ASCII)              */
  349.     unsigned char    revLevel[4];    /* Revision level (ASCII)          */
  350.     unsigned char    revData[8];    /* Revision data (ASCII)          */
  351. #endif
  352. }  ScsiInquiryData;
  353.  
  354.  
  355. /*
  356.  * The SCSI Peripheral type ID codes as return by the SCSI_INQUIRY command.
  357.  *
  358.  * SCSI_DISK_TYPE - Direct Access Device.
  359.  * SCSI_TAPE_TYPE - Sequential Access Device.
  360.  * SCSI_PRINTER_TYPE - Printer Device.
  361.  * SCSI_HOST_TYPE - Processor Device.
  362.  * SCSI_WORM_TYPE - Write-Once Read-Multiple Device.
  363.  * SCSI_ROM_TYPE  - Read-Only Direct Access Device.
  364.  * SCSI_SCANNER_TYPE - Scanner device.
  365.  * SCSI_OPTICAL_MEM_TYPE - Optical memory device.
  366.  * SCSI_MEDIUM_CHANGER_TYPE - Medium changer device.
  367.  * SCSI_COMMUNICATIONS_TYPE - Communications device.
  368.  * SCSI_NODEVICE_TYPE - Logical Unit not present or implemented.
  369.  *
  370.  * Note that codes 0xa-0x7e are reserved and 0x80-0xff are vendor unique.
  371.  */
  372. #define    SCSI_DISK_TYPE        0
  373. #define    SCSI_TAPE_TYPE        1
  374. #define    SCSI_PRINTER_TYPE    2
  375. #define    SCSI_HOST_TYPE        3
  376. #define    SCSI_WORM_TYPE        4
  377. #define    SCSI_ROM_TYPE        5
  378. #define    SCSI_SCANNER_TYPE    6
  379. #define    SCSI_OPTICAL_MEM_TYPE    7
  380. #define    SCSI_MEDIUM_CHANGER_TYPE    8
  381. #define    SCSI_COMMUNICATIONS_TYPE    9
  382. #define    SCSI_NODEVICE_TYPE    0x7f
  383.  
  384. /*
  385.  * Standard header for SCSI_MODE_SELECT commands for tapes.
  386.  */
  387.  
  388. typedef struct ScsiTapeModeSelectHdr {
  389. #if BYTE_ORDER == BIG_ENDIAN
  390.     unsigned char    reserved[2];    /* Reserved. */
  391.     unsigned char    reserved2:1;    /*  ""         */
  392.     unsigned char    bufferedMode:3;    /* Type of buffer to be done. */
  393.     unsigned char    speed:4;    /* Drive speed. */
  394.     unsigned char    length;        /* Block descriptor length. */
  395. #else
  396.     unsigned char    reserved[2];    /* Reserved. */
  397.     unsigned char    speed:4;    /* Drive speed. */
  398.     unsigned char    bufferedMode:3;    /* Type of buffer to be done. */
  399.     unsigned char    reserved2:1;    /*  ""         */
  400.     unsigned char    length;        /* Block descriptor length. */
  401. #endif
  402. } ScsiTapeModeSelectHdr;
  403. /*
  404.  * Format of a SCSI_START_STOP command. This is a group 0 command, but
  405.  * the command contents are different.
  406.  */
  407. typedef struct ScsiStartStopCmd {
  408. #if BYTE_ORDER == BIG_ENDIAN
  409.     unsigned char command;        /* 0x1b */
  410.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  411.                      * pass the command.  The device
  412.                      * has already been selected using
  413.                      * the "targetID" bit. */
  414.     unsigned char pad1        :4;    /* Reserved */
  415.     unsigned char immed        :1;    /* Immediate status bit */
  416.     unsigned char pad2;            /* Reserved */
  417.     unsigned char pad3;            /* Reserved */
  418.     unsigned char pad4        :6;    /* Reserved */
  419.     unsigned char loadEject    :1;    /* Load or eject medium */
  420.     unsigned char start        :1;    /* Start or stop medium */
  421.     unsigned char vendor57    :1;    /* Vendor unique bit */
  422.     unsigned char vendor56    :1;    /* Vendor unique bit */
  423.     unsigned char pad5        :4;    /* Reserved */
  424.     unsigned char linkIntr    :1;    /* Interrupt after linked command */
  425.     unsigned char link        :1;    /* Another command follows */
  426. #else
  427.     unsigned char command;        /* command code, defined below.  The
  428.                      * upper three bits of this are zero
  429.                      * to indicate the control block is
  430.                      * only 6 bytes long */
  431.     unsigned char immed        :1;    /* Immediate status bit */
  432.     unsigned char pad1        :4;    /* Reserved */
  433.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  434.                      * pass the command.  The device
  435.                      * has already been selected using
  436.                      * the "targetID" bit. */
  437.     unsigned char pad2;            /* Reserved */
  438.     unsigned char pad3;            /* Reserved */
  439.     unsigned char start        :1;    /* Start or stop medium */
  440.     unsigned char loadEject    :1;    /* Load or eject medium */
  441.     unsigned char pad4        :6;    /* Reserved */
  442.     unsigned char link        :1;    /* Another command follows */
  443.     unsigned char linkIntr    :1;    /* Interrupt after linked command */
  444.     unsigned char pad5        :4;    /* Reserved */
  445.     unsigned char vendor56    :1;    /* Vendor unique bit */
  446.     unsigned char vendor57    :1;    /* Vendor unique bit */
  447. #endif
  448. } ScsiStartStopCmd;
  449.  
  450.  
  451. /*
  452.  * Format of a SCSI_READ_EXT command.
  453.  */
  454.  
  455. typedef struct ScsiReadExtCmd {
  456. #if BYTE_ORDER == BIG_ENDIAN
  457.     unsigned char command;        /* command code. */
  458.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  459.                      * pass the command.  The device
  460.                      * has already been selected using
  461.                      * the "targetID" bit. */
  462.     unsigned char dpo        :1;    /* Disable page out. */
  463.     unsigned char fua        :1;    /* Force unit access. */
  464.     unsigned char pad1        :2;    /* Reserved. */
  465.     unsigned char relAddr    :1;    /* Who knows? */
  466.     unsigned char highAddr;        /* High bits of address. */
  467.     unsigned char highMidAddr;        /* High middle bits of address. */
  468.     unsigned char lowMidAddr;        /* Low middle bits of address. */
  469.     unsigned char lowAddr;        /* Low bits of address */
  470.     unsigned char pad2;            /* Reserved. */
  471.     unsigned char highCount;        /* High bits of number to transfer */
  472.     unsigned char lowCount;        /* Low bits of number to transfer */
  473.     unsigned char vendor    :2;    /* Vendor specific. */
  474.     unsigned char pad        :4;    /* Reserved. */
  475.     unsigned char flag        :1;    /* Flag bit. See SCSI doc. */
  476.     unsigned char link        :1;    /* Link commands. */
  477. #else
  478.     unsigned char command;        /* command code. */
  479.     unsigned char relAddr    :1;    /* Who knows? */
  480.     unsigned char pad1        :2;    /* Reserved. */
  481.     unsigned char fua        :1;    /* Force unit access. */
  482.     unsigned char dpo        :1;    /* Disable page out. */
  483.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  484.                      * pass the command.  The device
  485.                      * has already been selected using
  486.                      * the "targetID" bit. */
  487.     unsigned char highAddr;        /* High bits of address. */
  488.     unsigned char highMidAddr;        /* High middle bits of address. */
  489.     unsigned char lowMidAddr;        /* Low middle bits of address. */
  490.     unsigned char lowAddr;        /* Low bits of address */
  491.     unsigned char pad2;            /* Reserved. */
  492.     unsigned char highCount;        /* High bits of number to transfer */
  493.     unsigned char lowCount;        /* Low bits of number to transfer */
  494.     unsigned char link        :1;    /* Link commands. */
  495.     unsigned char flag        :1;    /* Flag bit. See SCSI doc. */
  496.     unsigned char pad        :4;    /* Reserved. */
  497.     unsigned char vendor    :2;    /* Vendor specific. */
  498. #endif
  499. } ScsiReadExtCmd;
  500.  
  501. /*
  502.  * The SCSI_WRITE_EXT command had the same format as SCSI_READ_EXT.
  503.  */
  504.  
  505. typedef struct ScsiReadExtCmd ScsiWriteExtCmd;
  506.  
  507. /* 
  508.  * Data returned by the SCSI_READ_BLOCK_LIMITS command.
  509.  */
  510.  
  511. typedef struct {
  512.     unsigned char    pad1;
  513.     unsigned char    max2;    /* MSB of max block size. */
  514.     unsigned char    max1;    /* ... */
  515.     unsigned char    max0;    /* LSB of max block size. */
  516.     unsigned char    min1;    /* MSB of min block size. */
  517.     unsigned char    min0;    /* LSB of min block size. */
  518. } ScsiBlockLimits;
  519.  
  520. /*
  521.  * Format of a SCSI_MODE_SENSE command. 
  522.  */
  523. typedef struct {
  524. #if BYTE_ORDER == BIG_ENDIAN
  525.     unsigned char command;        /* 0x1b */
  526.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  527.                      * pass the command.  The device
  528.                      * has already been selected using
  529.                      * the "targetID" bit. */
  530.     unsigned char pad1        :1;    /* Reserved */
  531.     unsigned char disableBlockDesc :1;    /* Disable block descriptor */
  532.     unsigned char pad2        :3;    /* Reserved */
  533.     unsigned char pageControl    :2;    /* Page Control */
  534.     unsigned char pageCode    :6;    /* Page Code */
  535.     unsigned char pad3;            /* Reserved */
  536.     unsigned char allocLen;        /* Allocation length. */
  537.     unsigned char vendor    :2;    /* Vendor unique. */
  538.     unsigned char pad4        :6;    /* Reserved */
  539. #else
  540.     unsigned char command;        /* 0x1b */
  541.     unsigned char pad2        :3;    /* Reserved */
  542.     unsigned char disableBlockDesc :1;    /* Disable block descriptor */
  543.     unsigned char pad1        :1;    /* Reserved */
  544.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  545.                      * pass the command.  The device
  546.                      * has already been selected using
  547.                      * the "targetID" bit. */
  548.     unsigned char pageCode    :6;    /* Page Code */
  549.     unsigned char pageControl    :2;    /* Page Control */
  550.     unsigned char pad3;            /* Reserved */
  551.     unsigned char allocLen;        /* Allocation length. */
  552.     unsigned char pad4        :6;    /* Reserved */
  553.     unsigned char vendor    :2;    /* Vendor unique. */
  554. #endif
  555. } ScsiModeSenseCmd;
  556.  
  557. /*
  558.  * Block descriptor returned by mode sense.
  559.  */
  560.  
  561. typedef struct {
  562.     unsigned char    density;    /* Density code. */
  563.     unsigned char    num2;        /* MSB of number of blocks. */
  564.     unsigned char    num1;        /* ... */
  565.     unsigned char    num0;        /* LSB of number of blocks. */
  566.     unsigned char    pad0;        /* Reserved. */
  567.     unsigned char    len2;        /* MSB of block length. */
  568.     unsigned char    len1;        /* ... */
  569.     unsigned char    len0;        /* LSB of block length. */
  570. } ScsiBlockDesc;
  571.  
  572. /*
  573.  * Format of a SCSI_REQUEST_SENSE command.
  574.  */
  575. typedef struct {
  576. #if BYTE_ORDER == BIG_ENDIAN
  577.     unsigned char command;        /* 0x1b */
  578.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  579.                      * pass the command.  The device
  580.                      * has already been selected using
  581.                      * the "targetID" bit. */
  582.     unsigned char pad1        :5;    /* Reserved */
  583.     unsigned char pad2;            /* Reserved */
  584.     unsigned char pad3;            /* Reserved */
  585.     unsigned char allocLen;        /* Allocation length. */
  586.     unsigned char clearCount    :1;    /* Clear counters. */
  587.     unsigned char vendor    :1;    /* Vendor unique. */
  588.     unsigned char pad4        :6;    /* Reserved */
  589. #else
  590.     unsigned char command;        /* 0x1b */
  591.     unsigned char pad1        :5;    /* Reserved */
  592.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  593.                      * pass the command.  The device
  594.                      * has already been selected using
  595.                      * the "targetID" bit. */
  596.     unsigned char pad2;            /* Reserved */
  597.     unsigned char pad3;            /* Reserved */
  598.     unsigned char allocLen;        /* Allocation length. */
  599.     unsigned char pad4        :6;    /* Reserved */
  600.     unsigned char vendor    :1;    /* Vendor unique. */
  601.     unsigned char clearCount    :1;    /* Clear counters. */
  602. #endif
  603. } ScsiRequestSenseCmd;
  604.  
  605. /*
  606.  * Format of a SCSI_READ_POSITION command.
  607.  */
  608.  
  609. typedef struct {
  610. #if BYTE_ORDER == BIG_ENDIAN
  611.     unsigned char command;        /* 0x34 */
  612.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  613.                      * pass the command.  The device
  614.                      * has already been selected using
  615.                      * the "targetID" bit. */
  616.     unsigned char pad1        :4;    /* Reserved */
  617.     unsigned char blockType    :1;    /* Block type. */
  618.     unsigned char pad2;            /* Reserved */
  619.     unsigned char pad3;            /* Reserved */
  620.     unsigned char pad4;            /* Reserved */
  621.     unsigned char pad5;            /* Reserved */
  622.     unsigned char pad6;            /* Reserved */
  623.     unsigned char pad7;            /* Reserved */
  624.     unsigned char pad8;            /* Reserved */
  625.     unsigned char vendor    :2;    /* Vendor unique. */
  626.     unsigned char pad9        :6;    /* Reserved */
  627. #else
  628.     unsigned char command;        /* 0x34 */
  629.     unsigned char blockType    :1;    /* Block type. */
  630.     unsigned char pad1        :4;    /* Reserved */
  631.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  632.                      * pass the command.  The device
  633.                      * has already been selected using
  634.                      * the "targetID" bit. */
  635.     unsigned char pad2;            /* Reserved */
  636.     unsigned char pad3;            /* Reserved */
  637.     unsigned char pad4;            /* Reserved */
  638.     unsigned char pad5;            /* Reserved */
  639.     unsigned char pad6;            /* Reserved */
  640.     unsigned char pad7;            /* Reserved */
  641.     unsigned char pad8;            /* Reserved */
  642.     unsigned char pad9        :6;    /* Reserved */
  643.     unsigned char vendor    :2;    /* Vendor unique. */
  644. #endif
  645. } ScsiReadPositionCmd;
  646.  
  647. /*
  648.  * Result of a SCSI_READ_POSITION command.
  649.  */
  650.  
  651. typedef struct {
  652. #if BYTE_ORDER == BIG_ENDIAN
  653.     unsigned char bop        :1;    /* Beginning of partition. */
  654.     unsigned char eop        :1;    /* End of partition. */
  655.     unsigned char pad0a        :3;    /* Reserved. */
  656.     unsigned char bpu        :1;    /* Block position unknown. */
  657.     unsigned char pad0b        :2;    /* Reserved. */
  658.     unsigned char partition;        /* Partition number. */
  659.     unsigned char pad2;            /* Reserved. */
  660.     unsigned char pad3;            /* Reserved. */
  661.     unsigned char firstBlock3;        /* First block location, MSB */
  662.     unsigned char firstBlock2;        /* ... */
  663.     unsigned char firstBlock1;        /* ... */
  664.     unsigned char firstBlock0;        /* First block location, LSB */
  665.     unsigned char lastBlock3;        /* Last block location, MSB */
  666.     unsigned char lastBlock2;        /* ... */
  667.     unsigned char lastBlock1;        /* ... */
  668.     unsigned char lastBlock0;        /* Last block location, LSB */
  669.     unsigned char pad12;        /* Reserved. */
  670.     unsigned char blocksInBuf2;        /* Blocks in buffer, MSB. */
  671.     unsigned char blocksInBuf1;        /* ... */
  672.     unsigned char blocksInBuf0;        /* Blocks in buffer, LSB. */
  673.     unsigned char bytesInBuf3;        /* Bytes in buffer, MSB. */
  674.     unsigned char bytesInBuf2;        /* ... */
  675.     unsigned char bytesInBuf1;        /* ... */
  676.     unsigned char bytesInBuf0;        /* Bytes in buffer, LSB. */
  677. #else
  678.     unsigned char pad0b        :2;    /* Reserved. */
  679.     unsigned char bpu        :1;    /* Block position unknown. */
  680.     unsigned char pad0a        :3;    /* Reserved. */
  681.     unsigned char eop        :1;    /* End of partition. */
  682.     unsigned char bop        :1;    /* Beginning of partition. */
  683.     unsigned char partition;        /* Partition number. */
  684.     unsigned char pad2;            /* Reserved. */
  685.     unsigned char pad3;            /* Reserved. */
  686.     unsigned char firstBlock3;        /* First block location, MSB */
  687.     unsigned char firstBlock2;        /* ... */
  688.     unsigned char firstBlock1;        /* ... */
  689.     unsigned char firstBlock0;        /* First block location, LSB */
  690.     unsigned char lastBlock3;        /* Last block location, MSB */
  691.     unsigned char lastBlock2;        /* ... */
  692.     unsigned char lastBlock1;        /* ... */
  693.     unsigned char lastBlock0;        /* Last block location, LSB */
  694.     unsigned char pad12;        /* Reserved. */
  695.     unsigned char blocksInBuf2;        /* Blocks in buffer, MSB. */
  696.     unsigned char blocksInBuf1;        /* ... */
  697.     unsigned char blocksInBuf0;        /* Blocks in buffer, LSB. */
  698.     unsigned char bytesInBuf3;        /* Bytes in buffer, MSB. */
  699.     unsigned char bytesInBuf2;        /* ... */
  700.     unsigned char bytesInBuf1;        /* ... */
  701.     unsigned char bytesInBuf0;        /* Bytes in buffer, LSB. */
  702. #endif
  703. } ScsiReadPositionResult;
  704.  
  705. /*
  706.  * Format of SCSI_LOCATE command.
  707.  */
  708.  
  709. typedef struct {
  710. #if BYTE_ORDER == BIG_ENDIAN
  711.     unsigned char command;        /* 0x2b */
  712.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  713.                      * pass the command.  The device
  714.                      * has already been selected using
  715.                      * the "targetID" bit. */
  716.     unsigned char pad1        :2;    /* Reserved */
  717.     unsigned char blockType    :1;    /* Block type. */
  718.     unsigned char changePartition :1;    /* Change partitions. */
  719.     unsigned char immediate    :1;    /* Immediate. */
  720.     unsigned char pad2;            /* Reserved */
  721.     unsigned char addr3;        /* Block address, MSB */
  722.     unsigned char addr2;        /* ... */
  723.     unsigned char addr1;        /* ... */
  724.     unsigned char addr0;        /* Block address, LSB */
  725.     unsigned char pad7;            /* Reserved */
  726.     unsigned char partition;        /* Partition */
  727.     unsigned char vendor    :2;    /* Vendor unique. */
  728.     unsigned char pad9        :6;    /* Reserved */
  729. #else
  730.     unsigned char command;        /* 0x2b */
  731.     unsigned char immediate    :1;    /* Immediate. */
  732.     unsigned char changePartition :1;    /* Change partitions. */
  733.     unsigned char blockType    :1;    /* Block type. */
  734.     unsigned char pad1        :2;    /* Reserved */
  735.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  736.                      * pass the command.  The device
  737.                      * has already been selected using
  738.                      * the "targetID" bit. */
  739.     unsigned char pad2;            /* Reserved */
  740.     unsigned char addr3;        /* Block address, MSB */
  741.     unsigned char addr2;        /* ... */
  742.     unsigned char addr1;        /* ... */
  743.     unsigned char addr0;        /* Block address, LSB */
  744.     unsigned char pad7;            /* Reserved */
  745.     unsigned char partition;        /* Partition */
  746.     unsigned char pad9        :6;    /* Reserved */
  747.     unsigned char vendor    :2;    /* Vendor unique. */
  748. #endif
  749. } ScsiLocateCmd;
  750.  
  751. /*
  752.  * Format of SCSI_PREVENT_ALLOW command.
  753.  */
  754.  
  755. typedef struct {
  756. #if BYTE_ORDER == BIG_ENDIAN
  757.     unsigned char command;        /* 0x1e */
  758.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  759.                      * pass the command.  The device
  760.                      * has already been selected using
  761.                      * the "targetID" bit. */
  762.     unsigned char pad1        :5;    /* Reserved. */
  763.     unsigned char pad2;            /* Reserved. */
  764.     unsigned char pad3;            /* Reserved. */
  765.     unsigned char pad4        :7;    /* Reserved. */
  766.     unsigned char prevent    :1;    /* 0 = allow, 1 = prevent */
  767.     unsigned char vendor    :2;    /* Vendor unique. */
  768.     unsigned char pad5        :6;    /* Reserved */
  769. #else
  770.     unsigned char command;        /* 0x1e */
  771.     unsigned char pad1        :5;    /* Reserved. */
  772.     unsigned char unitNumber    :3;    /* Logical Unit (LUN) to which to
  773.                      * pass the command.  The device
  774.                      * has already been selected using
  775.                      * the "targetID" bit. */
  776.     unsigned char pad2;            /* Reserved. */
  777.     unsigned char pad3;            /* Reserved. */
  778.     unsigned char prevent    :1;    /* 0 = allow, 1 = prevent */
  779.     unsigned char pad4        :7;    /* Reserved. */
  780.     unsigned char pad5        :6;    /* Reserved */
  781.     unsigned char vendor    :2;    /* Vendor unique. */
  782. #endif
  783. } ScsiPreventAllowCmd;
  784.  
  785. /*
  786.  * Format of a SCSI Inquiry Command.
  787.  */
  788.  
  789. typedef struct ScsiInquiryCommand {
  790. #if BYTE_ORDER == BIG_ENDIAN
  791.     unsigned char command;        /* 0x12 for SCSI Inquiry. */
  792.  
  793.     unsigned char unitNumber    :3;     /* Logical Unit Number to which
  794.                          * to pass the command. */
  795.     unsigned char reserved    :4;     
  796.     unsigned char evpd        :1;     /* Enable Vital Product Data. Selects
  797.                      * The type of inquiry data requested
  798.                      * by the initiator. */
  799.     unsigned char pageCode;        
  800.     unsigned char reserved2;        
  801.     unsigned char allocLength;        /* The number of bytes that the
  802.                      * initiator has allocated for
  803.                      * data returned from the Inquiry
  804.                      * command. */
  805.     unsigned char vendorUnique    :2;     /* Vendor Unique bits. */
  806.     unsigned char reserved3    :4;
  807.     unsigned char flag        :1;     /* Interrupt after linked command. */
  808.     unsigned char link        :1;     /* Another command follows. */
  809. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  810.     unsigned char command;        /* 0x12 for SCSI Inquiry. */
  811.  
  812.     unsigned char evpd        :1;    /* Enable Vital Product Data. Selects
  813.                      * The type of inquiry data requested
  814.                      * by the initiator. */
  815.     unsigned char reserved    :4;
  816.     unsigned char unitNumber    :3;    /* Logical Unit Number to which
  817.                      * to pass the command. */
  818.     unsigned char pageCode;
  819.     unsigned char reserved2;
  820.     unsigned char allocLength;        /* The number of bytes that the
  821.                      * initiator has allocated for data
  822.                      * returned from the Inquiry command.
  823.                      */
  824.     unsigned char link        :1;    /* Another command follows. */
  825.     unsigned char flag        :1;    /* Interrupt after linked command. */
  826.     unsigned char reserved3    :4;
  827.     unsigned char vendorUnique    :2;    /* Vendor Unique bits. */
  828. #endif
  829. } ScsiInquiryCommand;
  830.  
  831.  
  832. /*
  833.  * Format of a SCSI Mode Select command.
  834.  */
  835.  
  836. typedef struct ScsiModeSelectCommand {
  837. #if BYTE_ORDER == BIG_ENDIAN
  838.     unsigned char command;        /* 0x15, for Mode Select */
  839.     unsigned char unitNumber    :3;    /* Logical Unit Number to which
  840.                      * to pass the command. */
  841.     unsigned char pageFormat    :1;    /* 1 == SCSI-2;
  842.                      * Must be 1 for Exabyte robot. */
  843.     unsigned char reserved    :3;    
  844.     unsigned char savedPage    :1;    /* 0 == Changes are not permanent.
  845.                      * 1 == Changes are permanent
  846.                      * (stored in non-volatile memory).*/
  847.     unsigned char reserved2[2];
  848.     unsigned char paramListLength;    /* Length of the entire parameter
  849.                      * list. */
  850.     unsigned char vendorUnique    :2;    
  851.     unsigned char reserved3    :4;
  852.     unsigned char flag        :1;    /* Interrupt after linked command. */
  853.     unsigned char link        :1;    /* Another command follows. */
  854. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  855.     unsigned char command;        /* 0x15, for Mode Select */
  856.     unsigned char savedPage    :1;    /* 0 == Changes are not permanent.
  857.                      * 1 == Changes are permanent
  858.                      * (stored in non-volatile memory).*/
  859.     unsigned char reserved    :3;
  860.     unsigned char pageFormat    :1;    /* 1 == SCSI-2;
  861.                      * Must be 1 for Exabyte robot. */
  862.     unsigned char unitNumber    :3;    /* Logical Unit Number to which
  863.                      * to pass the command. */
  864.     unsigned char reserved2[2];
  865.     unsigned char paramListLength;    /* Length of the entire parameter
  866.                      * list. */
  867.     unsigned char link        :1;    /* Another command follows. */
  868.     unsigned char flag        :1;    /* Interrupt after linked command. */
  869.     unsigned char reserved3    :4;
  870.     unsigned char vendorUnique    :2;
  871. #endif
  872. } ScsiModeSelectCommand;
  873.  
  874.  
  875. /*
  876.  * Format of a SCSI Reserve Command.
  877.  */
  878.  
  879. typedef struct ScsiReserveCommand {
  880. #if BYTE_ORDER == BIG_ENDIAN
  881.     unsigned char command;        /* 0x16 for Reserve Command. */
  882.     unsigned char unitNumber    :3;    /* Logical Unit Number to which to
  883.                      * pass the command. */
  884.     unsigned char thirdParty    :1;
  885.     unsigned char thirdPartyDevID:3;
  886.     unsigned char extent    :1;    /* 0 == The device is reserved.
  887.                      * 1 == A series of elements,
  888.                      *      identified by the reserveID
  889.                      *      field and specified by the
  890.                      *      element list descriptor
  891.                      *      are reserved. A minimum of
  892.                      *      six bytes must be sent by
  893.                      *      the initiator. */
  894.     unsigned char reserveID;
  895.     unsigned char elemListLength[2];
  896.     unsigned char vendorUnique    :2;
  897.     unsigned char reserved    :4;
  898.     unsigned char flag        :1;
  899.     unsigned char link        :1;
  900. #else /* BYTE_ORDER == LITTLE_ENDIAN */
  901.     unsigned char command;
  902.     unsigned char extent    :1;    /* 0 == The device as a whole
  903.                      *      is reserved.
  904.                      * 1 == A series of elements,
  905.                      *      identified by the reserveID
  906.                      *      field and specified by the
  907.                      *      element list descriptor
  908.                      *      are reserved. A minimum of
  909.                      *      six bytes must be sent by
  910.                      *      the initiator. */
  911.     unsigned char thirdPartyDevID:3;
  912.     unsigned char thirdParty    :1;
  913.     unsigned char unitNumber    :3;    /* Logical Unit Number to which to
  914.                      * pass the command. */
  915.     unsigned char reserveID;
  916.     unsigned char elemListLength[2];
  917.     unsigned char link        :1;    
  918.     unsigned char flag        :1;
  919.     unsigned char reserved    :4;
  920.     unsigned char vendorUnique    :2;
  921. #endif
  922. } ScsiReserveCommand;
  923.  
  924.  
  925. #endif /* _SCSI_H */
  926.  
  927.  
  928.